package com.zhouhx.flow.task;


import com.zhouhx.flow.cache.DeviceFlowCache;
import com.zhouhx.flow.tasklist.TaskManager;
import com.zhouhx.flow.tasklist.entity.FlowInstance;
import com.zhouhx.flow.tasklist.enums.FlowInstanceStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @author : zhouhx
 * 流程任务
 * @date : 2024/5/3 14:47
 */
@Slf4j
@Component
public class DeviceFlowTask {
    /**
     * 线程池数量
     */
    private int poolSize = 4;
    /**
     *
     *有界队列
     */
    private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(512);
    /**
     *
     *   拒绝策略(什么也不做，直接忽略)
     */
    private RejectedExecutionHandler policy = new ThreadPoolExecutor.DiscardPolicy();
    /**
     * 线程池
     */
    private  ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(poolSize, poolSize,
            60, TimeUnit.SECONDS,queue, new CustomizableThreadFactory("auto-flow-task-scheduler"),policy);

    private volatile static DeviceFlowTask instance;

    public static DeviceFlowTask getInstance() {
        if (instance == null) {
            // 第一次检查，如果为空才进入同步代码块
            synchronized (DeviceFlowTask.class) {
                if (instance == null) {
                    // 第二次检查，如果为空才创建新的实例
                    instance = new DeviceFlowTask();
                }
            }
        }
        return instance;
    }

    /**
     *
     * 获取线程池
     * @author zhuohx
     * @param
     * @return java.util.concurrent.ThreadPoolExecutor
     * @throws
     * @version 1.0
     * @since  2024/2/20 13:39
     */
    public  ThreadPoolExecutor getThreadPool() {

        return this.threadPoolExecutor;
    }

    public void shutdown() {
        this.threadPoolExecutor.shutdown();
        log.info("释放线程池成功");
    }

    // 每个5s执行一次
    @Scheduled(cron = "0/2 * * * * ?")
    void execute() {
        Map<String, TaskManager> allTask = DeviceFlowCache.getAllTaskFlow();
        if (allTask.isEmpty()) {
            return;
        }
        try {
            allTask.forEach((k, v) -> {
                threadPoolExecutor.execute(() ->{
                    FlowInstance instance = v.getFlowInstance();
                    if(FlowInstanceStatusEnum.FINISH.getStatus() == instance.getCurrentFlowStatus()|| FlowInstanceStatusEnum.EXCEPTION.getStatus() == instance.getCurrentFlowStatus()){
                        // 流程结束，则移除
                        allTask.remove(k);
                    }else{
                        v.startTaskExecution();
                    }
                });
            });
        } catch (Exception e) {
            log.error("充电控制系统>>>>>>自动执行流程任务异常", e);
        }
    }
}
